home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 March / march_2001.iso / intercd / root / ^Palm / Games / 5x5 / 5x5.c next >
Encoding:
C/C++ Source or Header  |  1999-05-11  |  11.8 KB  |  459 lines

  1. /*
  2.  
  3.      5X5 - SIMPLE GAME FOR THE USR PILOT
  4.      Copyright (C) 1997,1998,1999 David A Pearson
  5.    
  6.      This program is free software; you can redistribute it and/or modify
  7.      it under the terms of the GNU General Public License as published by
  8.      the Free Software Foundation; either version 2 of the license, or 
  9.      (at your option) any later version.
  10.      
  11.      This program is distributed in the hope that it will be useful,
  12.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.      GNU General Public License for more details.
  15.      
  16.      You should have received a copy of the GNU General Public License
  17.      along with this program; if not, write to the Free Software
  18.      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. */
  21.  
  22. /*
  23.  * Modification history:
  24.  *
  25.  * $Log: 5x5.c,v $
  26.  * Revision 1.2  1999/05/11 12:53:13  davep
  27.  * Fix from Gary Chapman <garychapman@yahoo.com> which fixes a bug when
  28.  * tapping on the very edge of the play area.
  29.  *
  30.  * Revision 1.1  1997/06/21 07:55:05  davep
  31.  * Initial revision
  32.  *
  33.  */
  34.  
  35. #pragma pack( 2 )
  36.  
  37. /* Pilot header files. */
  38.  
  39. #include <Common.h>
  40. #include <System/SysAll.h>
  41. #include <UI/UIAll.h>
  42.  
  43. /* Local header files. */
  44.  
  45. #include "5x5.h"
  46.  
  47. /* Structure for the app prefs. */
  48.  
  49. struct strPrefs5x5
  50. {
  51.     int iMoves;
  52.     int iOn;
  53.     int playArea[ 5 ][ 5 ];
  54. };
  55.  
  56. /* Prototype local functions. */
  57.  
  58. void DrawForm( void );
  59. void DrawBox( int, int, int, int );
  60. void DrawPlayArea( void );
  61. void RefreshPlayArea( void );
  62. void InitGame( int );
  63. void RefreshScores( void );
  64. void YouWin( void );
  65. void NewGame( int );
  66. void MakeMove( EventPtr );
  67. void SaveGameState( void );
  68.  
  69. /* Global variables. */
  70.  
  71. static FormPtr  frm;                  /* Pointer to the form. */
  72. static FieldPtr fldMoves;             /* Pointer to the moves field. */
  73. static FieldPtr fldOn;                /* Pointer to the On field. */
  74. static FieldPtr fldOff;               /* Pointer to the Off field. */
  75. static int      playArea[ 5 ][ 5 ];   /* Flags for the play area. */
  76. static int      dirtyCells[ 5 ][ 5 ]; /* Track which cells need drawing */
  77. static int      iOn    = 0;           /* How many cells are filled? */
  78. static int      iMoves = 0;           /* Number of moves made. */
  79. static int      iLastX = -1;          /* X position of last penDown. */
  80. static int      iLastY = -1;          /* Y position of last penDown */
  81. static VoidHand hMoves;               /* Memory handle for moves field. */
  82. static VoidHand hOn;                  /* Memory handle for on field. */
  83. static VoidHand hOff;                 /* Memory handle for off field. */
  84.  
  85. /* Location of the play area. */
  86.  
  87. #define PA_TX     35            /* Top X */
  88. #define PA_TY     20            /* Top Y */
  89. #define PA_BX    155            /* Bottom X */
  90. #define PA_BY    140            /* Bottom Y */
  91. #define PA_CELL   24            /* Height/Width of a cell */
  92.     
  93. /* Macro to check that an event was in the play area. */
  94.  
  95. #define EVENT_IN_PLAYAREA( e ) ( e.screenX > PA_TX && \
  96.                                  e.screenX < PA_BX && \
  97.                                  e.screenY > PA_TY && \
  98.                                  e.screenY < PA_BY )
  99.  
  100. /* Macro to toggle the state of a cell. */
  101. #define TOGGLE_CELL( x, y )    ( playArea[ x ][ y ] = !playArea[ x ][ y ],\
  102.                                  dirtyCells[ x ][ y ] = 1,\
  103.                                  iOn += ( playArea[ x ][ y ] ? 1 : -1 ) )
  104.  
  105. /*
  106.  */
  107.     
  108. DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags )
  109. {
  110.     if ( cmd == sysAppLaunchCmdNormalLaunch )
  111.     {
  112.         short err;
  113.         EventType e;
  114.         int iExit = 0;
  115.  
  116.         FrmGotoForm( ID_Frm5x5 );
  117.  
  118.         InitGame( 0 );
  119.  
  120.         hMoves = MemHandleNew( 10 );
  121.         hOn    = MemHandleNew( 10 );
  122.         hOff   = MemHandleNew( 10 );
  123.         
  124.         while ( !iExit )
  125.         {
  126.             EvtGetEvent( &e, -1 );
  127.  
  128.             if ( SysHandleEvent( &e ) )
  129.             {
  130.                 continue;
  131.             }
  132.  
  133.             if ( MenuHandleEvent( ( void * ) 0, &e, &err ) )
  134.             {
  135.                 continue;
  136.             }
  137.  
  138.             switch ( e.eType )
  139.             {
  140.                 case frmLoadEvent :
  141.                     
  142.                     frm = FrmInitForm( e.data.frmLoad.formID );
  143.                     FrmSetActiveForm( frm );
  144.                     
  145.                     fldMoves = FrmGetObjectPtr( frm, FrmGetObjectIndex( frm, ID_FldMoves ) );
  146.                     fldOn    = FrmGetObjectPtr( frm, FrmGetObjectIndex( frm, ID_FldOn ) );
  147.                     fldOff   = FrmGetObjectPtr( frm, FrmGetObjectIndex( frm, ID_FldOff ) );
  148.                     
  149.                     break;
  150.                     
  151.                 case frmOpenEvent :
  152.                     
  153.                     DrawForm();
  154.                     RefreshScores();
  155.                     break;
  156.                     
  157.                 case penDownEvent :
  158.                     
  159.                     if ( EVENT_IN_PLAYAREA( e ) )
  160.                     {
  161.                         iLastX = ( ( e.screenX - PA_TX ) / PA_CELL );
  162.                         iLastY = ( ( e.screenY - PA_TY ) / PA_CELL );
  163.                     }
  164.                     else
  165.                     {
  166.                         FrmHandleEvent( FrmGetActiveForm(), &e );
  167.                     }
  168.                     break;
  169.                     
  170.                 case penUpEvent :
  171.                     
  172.                     if ( EVENT_IN_PLAYAREA( e ) )
  173.                     {
  174.                         MakeMove( &e );
  175.                     }
  176.                     else
  177.                     {
  178.                         FrmHandleEvent( FrmGetActiveForm(), &e );
  179.                     }
  180.                     break;
  181.                     
  182.                 case menuEvent :
  183.                     
  184.                     switch ( e.data.menu.itemID )
  185.                     {
  186.                         case ID_MnuItmNew :
  187.                             NewGame( iMoves );
  188.                             break;
  189.                             
  190.                         case ID_MnuItmAbout :
  191.                             FrmAlert( ID_AltAbout );
  192.                             break;
  193.                     }
  194.                     
  195.                     break;
  196.                     
  197.                 case ctlSelectEvent :
  198.                     
  199.                     NewGame( iMoves );
  200.                     break;
  201.                     
  202.                 case appStopEvent:
  203.                     
  204.                     FrmCloseAllForms();
  205.                     iExit = 1;
  206.                     break;
  207.                     
  208.                 default:
  209.                     
  210.                     FrmHandleEvent( FrmGetActiveForm(), &e );
  211.                     break;
  212.             }
  213.         }
  214.         
  215.         /* One would assume that you should free the handle here.
  216.            However, doing this gives an "invalid handle" error.
  217.            If you are reading this and you know what I'm doing wrong
  218.            then please feel free to drop me a line and let me know.
  219.         */
  220.         
  221.         /*MemHandleFree( hMoves );
  222.           MemHandleFree( hOn );
  223.           MemHandleFree( hOff );*/
  224.         
  225.         SaveGameState();
  226.     }
  227.     
  228.     return( 0 );
  229. }
  230.  
  231. /*
  232.  */
  233.  
  234. void DrawForm( void )
  235. {
  236.     FrmDrawForm( FrmGetActiveForm() );
  237.     DrawPlayArea();
  238. }
  239.  
  240. /*
  241.  */
  242.  
  243. void DrawPlayArea( void )
  244. {
  245.     DrawBox( PA_TX, PA_TY, PA_BX, PA_BY );
  246.     DrawBox( PA_TX + PA_CELL, PA_TY, PA_BX - PA_CELL, PA_BY );
  247.     DrawBox( PA_TX + PA_CELL + PA_CELL, PA_TY,
  248.              PA_BX - PA_CELL - PA_CELL, PA_BY );
  249.     DrawBox( PA_TX, PA_TY + PA_CELL, PA_BX, PA_BY - PA_CELL );
  250.     DrawBox( PA_TX, PA_TY + PA_CELL + PA_CELL, PA_BX,
  251.              PA_BY - PA_CELL - PA_CELL);
  252.  
  253.     RefreshPlayArea();
  254. }
  255.  
  256. /*
  257.  */
  258.  
  259. void RefreshPlayArea( void )
  260. {
  261.     RectangleType r;
  262.     int x, y;
  263.  
  264.     for ( x = 0; x < 5; x++ )
  265.     {
  266.         for ( y = 0; y < 5; y++ )
  267.         {
  268.             if ( dirtyCells[ x ][ y ] )
  269.             {
  270.                 r.topLeft.x = PA_TX + ( PA_CELL * x ) + 4;
  271.                 r.topLeft.y = PA_TY + ( PA_CELL * y ) + 4;
  272.                 r.extent.x  = PA_CELL - 8;
  273.                 r.extent.y  = PA_CELL - 8;
  274.                 
  275.                 if ( playArea[ x ][ y ] )
  276.                 {
  277.                     WinDrawRectangle( &r, 8 );
  278.                 }
  279.                 else
  280.                 {
  281.                     WinEraseRectangle( &r, 8 );
  282.                 }
  283.                 
  284.                 dirtyCells[ x ][ y ] = 0;
  285.             }
  286.         }
  287.     }
  288. }
  289.  
  290. /*
  291.  */
  292.  
  293. void DrawBox( int x1, int y1, int x2, int y2 )
  294. {
  295.     WinDrawLine( x1, y1, x1, y2 );
  296.     WinDrawLine( x1, y1, x2, y1 );
  297.     WinDrawLine( x2, y1, x2, y2 );
  298.     WinDrawLine( x1, y2, x2, y2 );
  299. }
  300.  
  301. /*
  302.  */
  303.  
  304. void InitGame( int iNew )
  305. {
  306.     struct strPrefs5x5 prefs;
  307.     
  308.     if ( iNew || !PrefGetAppPreferencesV10( (ULong) 'DAP0', 1, (VoidPtr) &prefs,
  309.                                             sizeof( prefs ) ) )
  310.     {
  311.         int x, y;
  312.  
  313.         iMoves = 0;
  314.         iOn    = 0;
  315.         
  316.         for ( x = 0; x < 5; x++ )
  317.         {
  318.             for ( y = 0; y < 5; y++ )
  319.             {
  320.                 playArea[ x ][ y ]   = 0;
  321.                 dirtyCells[ x ][ y ] = 1;
  322.             }
  323.         }
  324.         
  325.         TOGGLE_CELL( 1, 2 );
  326.         TOGGLE_CELL( 2, 1 );
  327.         TOGGLE_CELL( 2, 2 );
  328.         TOGGLE_CELL( 2, 3 );
  329.         TOGGLE_CELL( 3, 2 );
  330.     }
  331.     else
  332.     {
  333.         int x, y;
  334.         
  335.         iMoves = prefs.iMoves;
  336.         iOn    = prefs.iOn;
  337.  
  338.         for ( x = 0; x < 5; x++ )
  339.         {
  340.             for ( y = 0; y < 5; y++ )
  341.             {
  342.                 playArea[ x ][ y ]   = prefs.playArea[ x ][ y ];
  343.                 dirtyCells[ x ][ y ] = 1;
  344.             }
  345.         }
  346.     }
  347. }
  348.  
  349. /*
  350.  */
  351.  
  352. void RefreshScores( void )
  353. {
  354.     CharPtr sMoves = (CharPtr) MemHandleLock( hMoves );
  355.     CharPtr sOn    = (CharPtr) MemHandleLock( hOn );
  356.     CharPtr sOff   = (CharPtr) MemHandleLock( hOff );
  357.  
  358.     StrIToA( sMoves, iMoves   );
  359.     StrIToA( sOn,    iOn      );
  360.     StrIToA( sOff,   25 - iOn );
  361.     
  362.     MemHandleUnlock( hMoves );
  363.     MemHandleUnlock( hOn );
  364.     MemHandleUnlock( hOff );
  365.     
  366.     FldSetTextHandle( fldMoves, (Handle) hMoves );
  367.     FldSetTextHandle( fldOn,    (Handle) hOn    );
  368.     FldSetTextHandle( fldOff,   (Handle) hOff   );
  369.     
  370.     FldDrawField( fldMoves );
  371.     FldDrawField( fldOn    );
  372.     FldDrawField( fldOff   );
  373. }
  374.  
  375. /*
  376.  */
  377.  
  378. void YouWin( void )
  379. {
  380.     FrmAlert( ID_AltWin );
  381.     NewGame( 0 );
  382. }
  383.  
  384. /*
  385.  */
  386.  
  387. void NewGame( int iAsk )
  388. {
  389.     if ( ( iAsk ? FrmAlert( ID_AltNew ) == 0 : 1 ) )
  390.     {
  391.         InitGame( 1 );
  392.         RefreshPlayArea();
  393.         RefreshScores();
  394.     }
  395. }
  396.  
  397. /*
  398.  */
  399.  
  400. void MakeMove( EventPtr e )
  401. {
  402.     int x = ( ( e->screenX - PA_TX ) / PA_CELL );
  403.     int y = ( ( e->screenY - PA_TY ) / PA_CELL );
  404.     
  405.     if ( x == iLastX && y == iLastY )
  406.     {
  407.         TOGGLE_CELL( x, y );
  408.         
  409.         if ( x > 0 )
  410.         {
  411.             TOGGLE_CELL( x - 1, y );
  412.         }
  413.         if ( x < 4 )
  414.         {
  415.             TOGGLE_CELL( x + 1, y );
  416.         }
  417.         if ( y > 0 )
  418.         {
  419.             TOGGLE_CELL( x, y - 1 );
  420.         }
  421.         if ( y < 4 )
  422.         {
  423.             TOGGLE_CELL( x, y + 1 );
  424.         }
  425.  
  426.         ++iMoves;
  427.  
  428.         RefreshPlayArea();
  429.         RefreshScores();
  430.         
  431.         if ( iOn == 25 )
  432.         {
  433.             YouWin();
  434.         }
  435.     }
  436. }
  437.  
  438. /*
  439.  */
  440.  
  441. void SaveGameState( void )
  442. {
  443.     struct strPrefs5x5 prefs;
  444.     int x, y;
  445.  
  446.     prefs.iMoves = iMoves;
  447.     prefs.iOn    = iOn;
  448.     
  449.     for ( x = 0; x < 5; x++ )
  450.     {
  451.         for ( y = 0; y < 5; y++ )
  452.         {
  453.             prefs.playArea[ x ][ y ] = playArea[ x ][ y ];
  454.         }
  455.     }
  456.  
  457.     PrefSetAppPreferencesV10( 'DAP0', 1, &prefs, sizeof( prefs ) );
  458. }
  459.